from mydefine import *
from myutils import *
import os
import ipfshttpclient
import json
import yaml

def pullIndex(head_recved, db):
    block_size = head_recved['block_size']
    category = getModelCategory(head_recved['category'])
    indexType = head_recved['indexType']
    head_tosend = {}
    if (0 == len(block_size)):
        head_tosend = {"type": RESPONSE_ERROR, "status": "没有数据！"}
    else:
        if REQUEST_TYPEINDEX == indexType:
            cmd = 'select id,name,type,hash,extend,trans_model,trans_camera from tb_model where category = "%s"' % (category)
            status, rows = db.sqlexe(cmd)
            models = {"titles": ['id','name','type','hash','extend','trans_model','trans_camera'], "values": rows}
        if REQUEST_LABELINDEX == indexType:
            cmd = 'select id,name,tags,hash,extend,trans_model,trans_camera from tb_model where category = "%s"' % (category)
            status, rows = db.sqlexe(cmd)
            models = {"titles": ['id','name','tags','hash','extend','trans_model','trans_camera'], "values": rows}
        if REQUEST_MODELINDEX == indexType:
            cmd = 'select id,name,description,hash,extend,trans_model,trans_camera from tb_model where category = "%s"' % (category)
            status, rows = db.sqlexe(cmd)
            models = {"titles": ['id','name','content','hash','extend','trans_model','trans_camera'], "values": rows}
        # models["values"] = [[str(val) for val in row] for row in models["values"]]
        
        with open('config.yml', 'r') as conf_file:
            ymlConf = yaml.load(conf_file, Loader= yaml.FullLoader)
            ipfs_url = ymlConf['ipfs']['url']
        try:
            client = ipfshttpclient.connect(ipfs_url)
        except Exception as e:
            logger.error(e)
            return {"type": RESPONSE_ERROR, "status":e}
        values = []
        for (id,name,_,hash,extend,trans_model,trans_camera) in models["values"]:
            fcache = os.path.abspath(f'cache/{hash}.{extend}')
            if not os.path.exists(fcache):
                result = client.cat(hash)
                with open(fcache,'wb') as cfile:
                    cfile.write(result)
                    cfile.flush()
            values.append([str(id),name,_,fcache,extend,json.loads(trans_model),json.loads(trans_camera)])
        models["values"] = values
        head_tosend = {"type": RESPONSE_INDEXPULL, "status":status, "models": models}
    return head_tosend

def pushIndex(head_recved, db):
    block_size = head_recved['block_size']
    category = getModelCategory(head_recved['category'])
    values = head_recved['values']
    indexType = head_recved['indexType']
    head_tosend = {}
    if (0 == len(block_size)):
        head_tosend = {"type": RESPONSE_ERROR, "status": "没有数据！"}
    else:
        if REQUEST_LABELINDEX == indexType:
            cmd = 'select tags from tb_model where category = "%s"' % (category)
            status, pre_model_tags = db.sqlexe(cmd)
            if (None != status):
                return {"type": RESPONSE_ERROR, "status": status}
            pre_set = set()
            for sc in pre_model_tags:
                if sc[0] not in pre_set:
                    pre_set.add(sc[0])
            cur_tags = [value['tags'] for value in values]
            cur_set = set(cur_tags)
            print(f'cur:{cur_set}, pre:{pre_set}')
            # 增加的部分
            added_tags = cur_set.difference(pre_set)
            # 删除的部分
            removed_tags = pre_set.difference(cur_set)
            if len(added_tags) == 1 and len(removed_tags) == 1:
                addedOne = list(added_tags)[0]
                removedOne = list(removed_tags)[0]
                l_modify = [[addedOne, removedOne]]
                status, _ = db.sqlexe(f'update tb_tags set name=? where assetType="{ASSET_MODEL}" and category="{category}" and name=?', l_modify)
                if (None != status):
                    return {"type": RESPONSE_ERROR, "status": status}
                status, _ = db.sqlexe(f'update tb_model set tags=? where category="{category}" and tags=?', l_modify)
                if (None != status):
                    return {"type": RESPONSE_ERROR, "status": status}
            else:
                return {"type": RESPONSE_ERROR, "status": f'增数 = {len(added_tags)} , 删数 = {len(removed_tags)} , 为未定义行为.'}
        if REQUEST_TYPEINDEX == indexType:
            cmd = 'select type from tb_model where category = "%s"' % (category)
            status, pre_model_type = db.sqlexe(cmd)
            if (None != status):
                return {"type": RESPONSE_ERROR, "status": status}
            pre_set = set()
            for sc in pre_model_type:
                if sc[0] not in pre_set:
                    pre_set.add(sc[0])
            cur_type = [value['type'] for value in values]
            cur_set = set(cur_type)
            # 增加的部分
            added_type = cur_set.difference(pre_set)
            # 删除的部分
            removed_type = pre_set.difference(cur_set)
            if len(added_type) == 1 and len(removed_type) == 1:
                addedOne = list(added_type)[0]
                removedOne = list(removed_type)[0]
                l_modify = [[addedOne, removedOne]]
                status, _ = db.sqlexe(f'update tb_type set name=? where assetType="{ASSET_MODEL}" and assetType="{ASSET_MODEL}" and category="{category}" and name=?', l_modify)
                if (None != status):
                    return {"type": RESPONSE_ERROR, "status": status}
                status, _ = db.sqlexe(f'update tb_model set type=? where category="{category}" and type=?', l_modify)
                if (None != status):
                    return {"type": RESPONSE_ERROR, "status": status}
            else:
                return {"type": RESPONSE_ERROR, "status": f'增数 = {len(added_type)} , 删数 = {len(removed_type)} , 为未定义行为.'}
        if REQUEST_MODELINDEX == indexType:
            cmd = 'select description from tb_model where category = "%s"' % (category)
            status, pre_model_scs = db.sqlexe(cmd)
            if (None != status):
                return {"type": RESPONSE_ERROR, "status": status}
            pre_set = set()
            for sc in pre_model_scs:
                if sc[0] not in pre_set:
                    pre_set.add(sc[0])
            cur_scs = [value['content'] for value in values]
            cur_set = set(cur_scs)
            # 增加的部分
            added_scs = cur_set.difference(pre_set)
            # 删除的部分
            removed_scs = pre_set.difference(cur_set)
            if len(added_scs) == 1 and len(removed_scs) == 1:
                addedOne = list(added_scs)[0]
                removedOne = list(removed_scs)[0]
                l_modify = [[addedOne, removedOne]]
                status, _ = db.sqlexe(f'update tb_sc set name=? where category="{category}" and name=?', l_modify)
                if (None != status):
                    return {"type": RESPONSE_ERROR, "status": status}
                status, _ = db.sqlexe(f'update tb_model set description=? where category="{category}" and description=?', l_modify)
                if (None != status):
                    return {"type": RESPONSE_ERROR, "status": status}
            else:
                return {"type": RESPONSE_ERROR, "status": f'增数 = {len(added_scs)} , 删数 = {len(removed_scs)} , 为未定义行为.'}
        head_tosend = {"type": RESPONSE_INDEXPUSH, "status":status, "models": {}}
    return head_tosend
